

#include "stm32f4xx_hal.h"
#include "timer.h"

#define TIMER7_MAX_COUNT  40000  // 4MHz, 10ms
static TIM_HandleTypeDef htim7;

int HwMicroTimerInit(void)
{
    TIM_ClockConfigTypeDef sClockSourceConfig = {0};
    TIM_MasterConfigTypeDef sMasterConfig = {0};

    __HAL_RCC_TIM7_CLK_ENABLE();

    htim7.Instance = TIM7;
    htim7.Init.Prescaler = 21 - 1;  // 84MHZ / 21 = 4MHZ
    htim7.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim7.Init.Period = TIMER7_MAX_COUNT - 1;
    htim7.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
    if (HAL_TIM_Base_Init(&htim7) != HAL_OK)
    {
        while(1);
    }
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    if (HAL_TIM_ConfigClockSource(&htim7, &sClockSourceConfig) != HAL_OK)
    {
        while(1);
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim7, &sMasterConfig) != HAL_OK)
    {
        while(1);
    }
    // HAL_NVIC_SetPriority(TIM7_IRQn, 1, 8);
    // HAL_NVIC_EnableIRQ(TIM7_IRQn);
    // HAL_TIM_Base_Start_IT(&htim7);
    HAL_TIM_Base_Start(&htim7);
    return 0;
}

static uint32_t HwMicroTimerGetCnt(void)
{
    return __HAL_TIM_GET_COUNTER(&htim7);
}

int HwMicroTimerDelayUs(uint32_t us) // us should be less than 1000
{
    us *= 4;
    us %= TIMER7_MAX_COUNT;
    uint32_t start = HwMicroTimerGetCnt();
    if (us + start > TIMER7_MAX_COUNT) {
        while (HwMicroTimerGetCnt() >= start);
        us -= (TIMER7_MAX_COUNT - start);
        start = 0;
    }
    while ((HwMicroTimerGetCnt() - start) < us);
    return 0;
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    (void) htim;
}

void TIM7_IRQHandler(void)
{
}
